/**
 * Project Name:ctower-system-api
 * File Name:HttpHelper.java
 * Package Name:com.ec.ctower.utils
 * Date:2017年1月11日下午5:28:50
 * Copyright (c) 2017, fhlin0611@foxmail.com All Rights Reserved.
 *
*/

package com.foryou.swkj.core.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.net.URLEncoder;
import java.util.*;

/**
 * ClassName:HttpHelper <br>
 * Function: <p>http辅助类,采用建造者模式. <br>
 * 用于接口测试.更丰富的功能有待开发<br>
 * 具体的使用方法，请参照main方法的使用示例<br>
 * 因本工具类的使用局限性,<br>
 * 如有需要可使用Chrome插件Postman或其他http测试工具<p>
 * Reason:	<p> 因开发APP,客户端页面未评审完,<br>
 * 为了保证编写的接口的可用性和便于以后开发人员的工作交接,<br>
 * 故编写此类辅助编写测试用例. <br><p>
 * Date:     2017年1月11日 下午5:28:50 <br>
 * @author   Dante Fung
 * @version  1.0.1
 * @since    JDK 1.7
 * @see 	 
 */
public class HttpHelper {
	
	private static final Logger logger = LoggerFactory.getLogger(HttpHelper.class);
	
	public static final String POST = "POST";
	public static final String GET = "GET";
	/////////////////////////////////////////////////////////////////////
	
	/**
	 * NEED TO INITAIL VARIABLE
	 */
	// REQUIRED PATAMETER
	private String URL;
	
	private final String REQUEST_SYS;
	
	private final String KEY;
	
	private final String ENCODE_DATE;
	
	// OPTIONAL PARAMETER
	// TODO: YOU CAN ADD SOME PERSONAL PARAMETER.
	private final String CONTENT;// 格式为JSON
	
	private final Map PARAMS;
	
	private final Map HEADERS;
	/**
	 * BUILDER PATTERN 
	 */
	public static class Builder{
		
		// REQUIRED PARAMETER
		private final String URL;
		private final String REQUEST_SYS;
		private final String KEY;
		private final String ENCODE_DATE;
	    // OPTIONAL PARAMETER
		private String CONTENT;
		private Map<String,String> PARAMS;
		private Map<String,String> HEADERS;
		
		public Builder(String url){
			this.URL = url;
			this.REQUEST_SYS = null;
			this.KEY = null;
			this.ENCODE_DATE = null;
		}
		
		public Builder(String requestSys, String key, String encodeDate, String url){
			this.REQUEST_SYS = requestSys;
			this.KEY = key;
			this.ENCODE_DATE = encodeDate;
			this.URL = url;
		} 
		
		
		// TODO:YOU CAN EXTEND SOME FUNCTION.
		public Builder content(String content){
			this.CONTENT = content;
			return this;
		}
		
		public Builder params(Map<String,String> params){
			this.PARAMS = params;
			return this;
		}
		
		public Builder headers(Map<String,String> headers){
			this.HEADERS = headers;
			return this;
		}
		
		public HttpHelper build(){
			return new HttpHelper(this);
		}
	}
	
	// 私有构造器
	private HttpHelper(Builder builder)
	{
		REQUEST_SYS = builder.REQUEST_SYS;
		KEY = builder.KEY;
		ENCODE_DATE = builder.ENCODE_DATE;
		CONTENT = builder.CONTENT;
		URL = builder.URL;
		PARAMS = builder.PARAMS;
		HEADERS = builder.HEADERS;
	}
	
	
	
	
	
	////////////////////////////////////方法///////////////////////////////////////
	private CloseableHttpClient httpClient = MyHttpUtils.createDefaultSsLClient();
	
	 /**
     * 
     * doRequest:请求api工程. <br/>
     * 1、url:http://localhost:8080/api/
     * 2、必带参数：key=key rquestSys=ctower-app time=new Date() 可选参数：如：content={"sailingId":"22"}
     * 默认使用GET方式请求
     * @author Dante Fung
     * @return
     * @throws Exception
     * @since JDK 1.7
     */
	public Object doRequest()throws Exception {
		return doRequest(GET);
	}
	
	 /**
     * 
     * doRequest:请求api工程. <br/>
     * 1、url:http://localhost:8080/api/
     * 2、必带参数：key=key rquestSys=ctower-app time=new Date() 可选参数：如：content={"sailingId":"22"}
     * @author Dante Fung
     * @type GET POST  可使用  HttpHelper.POST、HttpHelper.GET
     * @return
     * @throws Exception
     * @since JDK 1.7
     */
	public Object doRequest(String type) throws Exception {
		Object result = null;
		switch(type){
		   case GET:
			         result = get();
			         break;
		   case POST:
			         result = post();
			         break;
		   default:
			   // do nothing...
			   break;
		}
		
		return result;
	}
	
	/**
	 * 
	 * get:Http的GET请求. <br/>
	 *
	 * @author Dante Fung
	 * @return
	 * @throws Exception
	 * @since JDK 1.7
	 */
	private String get() throws Exception {
		if((StringUtils.isNotBlank(KEY)
				&& StringUtils.isNotBlank(REQUEST_SYS)
			    && StringUtils.isNotBlank(ENCODE_DATE))
			    || StringUtils.isNotBlank(CONTENT)){
			String param = "?key=" + KEY + "&requestSys=" + REQUEST_SYS + "&time=" + URLEncoder.encode(new Date().getTime()+"")
			+ "&content=" + URLEncoder.encode(CONTENT)/*JSON格式*/;
			URL = URL + param;
		}
		if (null != PARAMS) {
			int count = 0;
			Set<Map.Entry<String,String>> entries = PARAMS.entrySet();
			for(Map.Entry<String, String> entry : entries){
				String param = null;
				if (count == 0) {
					param = String.format("?%s=%s",entry.getKey(), entry.getValue());
				} else {
					param = String.format("&%s=%s",entry.getKey(), entry.getValue());
				}
				URL+=param;
				++count;
			}
		}
		System.out.println(">>>>>>>>>>>>>>>>>请求地址:" + URL);
		HttpGet get = new HttpGet();
		get.setHeader("Content-Type",
				"application/x-www-form-urlencoded;charset=utf-8");
		this.setHeader(get);
		get.setURI(new URI(URL));
		get.releaseConnection();
		HttpResponse response = httpClient.execute(get);
		HttpEntity entity = response.getEntity();
		byte[] datas = IOUtils.toByteArray(entity.getContent());
		EntityUtils.consume(entity);
		String result = new String(datas,"UTF-8");
		return result;
	}
	
	/**
	 * 
	 * post:Http的POST请求. <br/>
	 *
	 * @author Dante Fung
	 * @return
	 * @since JDK 1.7
	 */
	private String post(){
		try {
			HttpPost post = new HttpPost();
			post.setURI(new URI(URL));
			post.setEntity(new UrlEncodedFormEntity(getParams(), HTTP.UTF_8));
			post.setHeader("Content-Type",
					"application/x-www-form-urlencoded;charset=utf-8");
			this.setHeader(post);
			logger.info(">>>>>>>>>>>>>>>请求地址:" + post.getURI());
			logger.info(">>>>>>>>>>>>>>>请求正文:"+new String(IOUtils.toByteArray(post.getEntity().getContent()),"UTF-8"));
			
			HttpResponse response = httpClient.execute(post);
			HttpEntity entity = response.getEntity();
			if (null == entity) {
				return new String(new byte[0],"UTF-8");
			}
			byte[] datas = IOUtils.toByteArray(entity.getContent());
			EntityUtils.consume(entity); // Consume response content
			return new String(datas,"UTF-8");
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}
	
	/**
	 * 
	 * getParams:获取请求 参数. <br/>
	 *
	 * @author Dante Fung
	 * @return
	 * @since JDK 1.7
	 */
	private List<NameValuePair> getParams(){
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		if(StringUtils.isNotBlank(KEY)
				&& StringUtils.isNotBlank(REQUEST_SYS)
			    && StringUtils.isNotBlank(ENCODE_DATE)){
			params.add(new BasicNameValuePair("key",KEY));
			params.add(new BasicNameValuePair("requestSys",REQUEST_SYS));
			params.add(new BasicNameValuePair("time",new Date().getTime()+""));
		}
		if(null != PARAMS){
			Set<Map.Entry<String,String>> entries = PARAMS.entrySet();
			for(Map.Entry<String, String> entry : entries){
				params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
		}
		return params;
	}
	
	/**
	 * 
	 * setHeader:设置HTTP请求的头信息. <br/>
	 *
	 * @author Dante Fung
	 * @param hrb
	 * @since JDK 1.7
	 */
	private void setHeader(HttpRequestBase hrb) {
		if(null != HEADERS){
			Set<Map.Entry<String,String>> entries = HEADERS.entrySet();
			for(Map.Entry<String, String> entry : entries){
				hrb.setHeader(entry.getKey(), entry.getValue());
			}
		}
	}
	
	/*
	 * 
	 * main:使用示例. <br/>
	 *
	 * @author Dante Fung
	 * @param args
	 * @throws Exception
	 * @since JDK 1.7
	 */
	public static void main(String[] args) throws Exception {
		System.out.println("==========Request================");
		HttpRequest request = new BasicHttpRequest("POST", "/",
			    HttpVersion.HTTP_1_1);
		System.out.println(request.getRequestLine().getMethod());
		System.out.println(request.getRequestLine().getUri());
		System.out.println(request.getProtocolVersion());
		System.out.println(request.getRequestLine().toString());
		System.out.println("===========Entity================");
		StringEntity myEntity = new StringEntity("important message",
			    Consts.UTF_8);
		System.out.println(myEntity.getContentType());
		System.out.println(myEntity.getContentLength());
		System.out.println("（请求/相应）实体内容" + EntityUtils.toString(myEntity));
		System.out.println(EntityUtils.toByteArray(myEntity).length);
		
		
		// URL  http://14.215.108.234/mall/barge/prestowage/takeup/151
		// PARAM 
		/*
		 *  bayNo:01
			rowNo:04
			tieNo:01
			containerNo:644
			
			
			backurl
			names:wendy
			password:123456
			vaildCode:1015
		 */
		
		// ------------登录-----------
		/*logger.info(">>>>>>>>>>>>>>>>>>开始：登录<<<<<<<<<<<<<<<<<<<<<<");
		// 模拟请求参数
	    String url = "http://14.215.108.234/mall/login/doLogin";
	    // 请求参数
	    Map<String,String> params = new HashMap<String,String>();
	    params.put("names", "wendy");
	    params.put("wendy", "123456");
	    params.put("vaildCode", "9862");
	    params.put("backurl", "");
	    
		// 1、创建Http工具类
		HttpHelper helper = new HttpHelper
		.Builder(null, null, null, url)
		.params(params)
		.build();
		
		// 2、发送请求
		Object result = helper.doRequest(HttpHelper.POST);
		logger.info("#####################################");
		logger.info(String.format("原始报文：[%s]", result));
		try {
			JSONObject resultJSO = JSONObject.parseObject(String.valueOf(result));
			logger.info(String.format("请求结果：[%s]", resultJSO.getString("msg")));
			logger.info(String.format("返回码：[%s]", resultJSO.getString("resultCode")));
		} catch (Exception e) {
			logger.error("出错啦~返回的信息不是JSON格式!");
		}
		logger.info("#####################################");
		logger.info(">>>>>>>>>>>>>>>>>>结束：登录<<<<<<<<<<<<<<<<<<<<<<");*/
		// ------------测试-----------
		logger.info(">>>>>>>>>>>>>>>>>>开始：测试接口<<<<<<<<<<<<<<<<<<<");
		// 模拟请求参数
	    String url = "http://14.215.108.234/mall/barge/prestowage/takeup/151";
	    // 请求参数
	    Map<String,String> params = new HashMap<String,String>();
	    params.put("bayNo", "01");
	    params.put("rowNo", "04");
	    params.put("tieNo", "01");
	    params.put("containerNo", "644");
	    // 请求头
	    Map<String,String> headers = new HashMap<String,String>();
	    headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
	    headers.put("Accept-Encoding", "gzip, deflate, sdch");
	    headers.put("Accept-Language", "zh-CN,zh;q=0.8");
	    headers.put("Connection", "keep-alive");
	    headers.put("Cookie", "rememberMe=ElH6KCZHgjEc8Vbk6BSbEjWSvIYe/jG/Lzhwvx/+N8yCipgOziPerzKWlvajPkUfsVPAdv6waF8eN7IsxkC/Y5SfB/NYqvul3JZmipbG3SaHVNL/ZAdnMwYCtXLcHMfVyO8iEqgl5oEmuW7IR0RUoAE/eaKzAxKw4QKOmuzd35zweHVUCQdWSGwQsRHamkrNLJg+zi+SxOef1AopKBnUkGtpSQLg2AJ4tTwXyJYdZWfts0/dayTpMYqan6NNEdGfdegURKGfly36g37gdoE1ZEIrO5LxriYJZSETHVQTOInCzuQLqHq5qvaw+imCzo0XXIHhATeexZPMi/63szGxKlILQFKSn2V+LI4LbaPZgXFMJGafVgQl0mpvWbaqsXzHvt80pVfITinDtWJNk/nCsaUdbjDnPWG5GdI13BkyUG+ySW6mVx3vafNmQMc6rEfn7Uim8CFR3QNPf3XDY7N22hFu2kA6xIp2wGlxiHJ05fBIA8dK9NFNT3Xwmc7YwttWvpiUQAkcDD1j38NWs5C6lXpTWhoPQyVSoNvzVaeuGJq1JL7bMuSL4R91277sfJioZivDJTiZzBsien4tP/3j7AgSk02X7j03uI4tljqWRkig9sxh7x94qLZD96YmvSAyiASSHHZL941dT79vK5KPNm0U+/CMu7gaZa24kRtA0M+vedjLmw3W2HZFyGZRgsmZviChe5Xsz+prrBsMTCTH3K//33roNLSC8HmR3jfroJ+/+bZAZUAvI0dbRBuMe3HiMoJ0o86uF+V6Yss8Wgz/EzxN6yBiINx47TMb1SKkF81Z2gNKvwo0/KCGihi4eqsaFQBrQXP+9rVNz7lJm+iBPFVAdfDM4WQ/+Cprm81GVZMDv0WbQ1sj97r1RhmUZE5ml7pCkj95/XmUnYbgoAcA2NaIgkcNpnYsUjenqc60Cv3GBxDzM46BfywFgOgTF4wg1IbDR2vEoAEH2LjeiZXeQnFaJKI5SyzWhI8eIizPJraoHKsk7HkGxXsW/zp4D57xW0GF60WmdcO1fp7lasKBGYq2P6zgXexnXLCbTS83H8tWTzOoSHo408OhABiEerduZjHhJPXyc7qPCexGDUh0RTx3XPq6Tt79iF095zjECVoyGimU1e/gQjl2bNJaE4q4sPo5X6wbIZIeEKA3lhMEUmcADLu62tPx0BqR9Znz67uR4k/fkgOqiTVSmS3LtQkB; JSESSIONID-mall=4rTPY9QJlyw11SqpqfwB2JJrLGn43yKYGYNgTWvvjY6njRL223hQ!1725278090; roleCookie=0VXNsPeg7ZneQG6WVLuzZFUBK/KOeu++1KSnJHNPyAc3/55X7wzlbIwUeAROy089sosbvYV10qGq3rD/x88oJq3lSql0OhGJL6YnY0t5i8cODBltzADkDp96yAtVWQTC2ezfvgHnB3sn27eHqd6n1YmXDSaXy69jTvGz0PaJpdktw9KktuTZr38QZGPPWyUE1WNtB9GYy/1okvSPnU+N3P8carCRPWW2bCO8KLWprOW2m/pHwAHtPkeuXJsQiAgKs49tcp5M4p44YlhsDjPllxxRzX01gCu/VvPSHhEwgWIgDy6IjEx3TsFlrd0yCT2uBv3BPsv3YWQ7PD2+/B6ANQ3YvMqAq8v18c1BRPz3UGX5MDMiS2bUVC3D0qS25NmvCDBRckPLg+nyLW0QfIlM6cEKw+sd1nmPIcZ3YPdFW9uZzWvz+/deN8/QFrskQDoa6NidLD/4fOxL6lgVv1BNj7OPbXKeTOKeLG41dPTZP0PrDK8lTP111upDTQgMNAZOwfaQ1E3NRAgDLFnstsf7gbKLG72FddKh9AHWMlwWWenfwQtJ7zeM114fvQtgcoGsYdOg97E6UUK6tCY2O1HBO/jVWPrywBDjcupfhNTt7z8F5jQcUNHFyvRPTNZRBxm27lTZxF1IPxTCqU7tIAFfaFe2/5IUd/0SmMSkeOnuuuHqQ00IDDQGTpwIiP0vfnL9vONYdRsvfLUvpidjS3mLxw4MGW3MAOQOhqyylqewRPsDLFnstsf7gdfAADyVP4zaqQIpklfJq2J3Qryyx10oGyAPLoiMTHdOJ9cKWVW4Jg9XnAD3+Z5RAupDTQgMNAZOxqe1sv9vbZYhiNaisAy5bY78VOvCwmYeMRtWN6jbaZ3CTkPx3w1XQi+mJ2NLeYvHDgwZbcwA5A7UDP3K0J57pc1yCJWvTJUUIuWfZJ2iMYCdoHsH7S7bOsN2aMJOOwy8wQrD6x3WeY+gyT9EXt7+j0bZy33EjKLHu01Einq1/FQwCU/HE84H8zQWpFAKzVk0m9u1KMQJQDShVL2GU2gCWuEUH9Yn20MA9MXMtBaEVudGmokzYfEOgtxUMj2KUeChPIbr9SFsja4WDWIjIan+JmAQSt5R49/bBX2AmvKGQEwvpidjS3mLxw4MGW3MAOQO1oFfQli6qBCsEScThkplKfkdQenTYRvNv+tcHwBQkcKO/FTrwsJmHtINftWBHgzITfsxK84oZgNZuOynnbodCrixKuZbKV011voejUxH179aDfDbAxl0zMoftmrdmUuX; SHARE_USER_INFO_O2O=THEqxs8MdS4ulrd5g3VPztQr3sr2WX0VgTs7kOA6vWkWBq7Ir7E1u4A3s9o8o+bC5ZGxNDMooWk63malvV/h6KNQm1pf2wdHO5Y4PZfGpdcvpidjS3mLxxi8W/T9dkFi; merchantCookie=h1MtTy2bKNeVkLJkDzfEPEWemRut/KSyW8nKYiE23q8IXTlWCjlUh2+YqEe+GiXHfDsDROkHopdmgUyDy3yphqrNDbR49yTVfhCNIUJln/nXUgxlZkEk96sFu8cyFr/JBX2AmvKGQExEjoaC3bBmRtmS3BJaeWXY9hCs+FNR8SFPvFJiB1+C8UfSDx2oajnx3d1ySp8DgnR/EGRjz1slBNVjbQfRmMv9aJL0j51Pjdz/HGqwkT1ltmwjvCi1qazltpv6R8AB7T5HrlybEIgICrOPbXKeTOKeOGJYbA4z5ZccUc19NYArv1bz0h4RMIFiIA8uiIxMd07BZa3dMgk9rgb9wT7L92FkOzw9vvwegDUN2LzKgKvL9fHNQUT891Bl+TAzIktm1FQtw9KktuTZrwgwUXJDy4Pp8i1tEHyJTOnBCsPrHdZ5jyHGd2D3RVvb+6sW/0GtpNDP0Ba7JEA6GujYnSw/+HzsS+pYFb9QTY+zj21ynkzinixuNXT02T9D6wyvJUz9ddbqQ00IDDQGTsH2kNRNzUQIiMcNpstfSf6kKbVYWXWlCNmS3BJaeWXYvSYVtVdEh8ZxYhXyYoZuTaQ0d4IdqTViAyxZ7LbH+4EpLfGBcxkfYdmS3BJaeWXYpBQunLazThLvtV2+c5UX8awjOmSWiHDrWzCgeUDZ1d77dcZAFU2R0Jsi+Lm9Xi8KYwLyyjwzjpFNDyYpgtnmlbaig1If7qClqx3oNPC8wdm5Mx6br1ZK3x2BreP86rlpQptpGBuxRN3A7jRoRGXk5Jjrb8CAcpPCp/HWkPhHMcXisN7HBDGr5CmO40o+B7dmMNmWFPqvUvbsARg0Js6dTarBvUT+S/Hbi/g+ZtCLtltHH2ZWD9ot+5si+Lm9Xi8KlfinNJEipawODBltzADkDtQM/crQnnulzXIIla9MlRQi5Z9knaIxgDrWDjr4gsYEiZS3AOzARd1FBhY1Hzgqdhc/JEi42cRKPW9+DfoTysDB61JA3iEM4LfWIJNOflGXnhFsPqdohkrzcWZ2f18qz5Lba3thwKsb2E4EWuaTCs/8YVCniaiX8/qb8DIg+MePJBwJUCeTfLgQiqiaetT6BbvSs0YIhK3PoMk/RF7e/o/C/6gljh7WdRXsMUcQTgt2oIkyR4fj+/k64KYe3lMAO6wjOmSWiHDrJmk9It1U6pI+JKcFHNfb+tkv+VkGNMIkwGG99Y8bW+9IJnI95Ek15i9wdOt2yOkt");
	    headers.put("Host", "14.215.108.234");
	    headers.put("Upgrade-Insecure-Requests", "1");
	    headers.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
	    
		// 1、创建Http工具类
		HttpHelper helper = new HttpHelper
		.Builder(null, null, null, url)
		.params(params)
		.headers(headers)
		.build();
		
		// 2、发送请求
		Object result = helper.doRequest(HttpHelper.POST);
		logger.info("#####################################");
		logger.info(String.format("原始报文：[%s]", result));
		try {
			JSONObject resultJSO = JSONObject.parseObject(String.valueOf(result));
			logger.info(String.format("请求结果：[%s]", resultJSO.getString("msg")));
			logger.info(String.format("返回码：[%s]", resultJSO.getString("resultCode")));
		} catch (Exception e) {
			logger.error("出错啦~返回的信息不是JSON格式!");
		}
		logger.info("#####################################");
		
		logger.info(">>>>>>>>>>>>>>>>>>>结束：测试接口<<<<<<<<<<<<<<<<<<");
	}
}